import struct
from ss.file import File
from ss.record import Record, SSNAME

__author__ = 'andrey'

class ItemRecord(Record):
    def _get_struct_type(self):
        return super(ItemRecord, self)._get_struct_type() + 'hh' + SSNAME + '2s2sLLL'
    def name(self):
        if self._data[7] == 0:
            return self._data[6]
        raise NotImplementedError('extract name from names.dat')
    @property
    def isfile(self):
        return self._data[3] == 2
    @property
    def isproject(self):
        return self._data[3] == 1
    @property
    def ext(self):
        return self._data[9]
    @property
    def last_version(self):
        return self._data[11]

    def __str__(self):
        return str(self._data)

ACTION_LABELED = 0

class VersionRecord(Record):
    '''VersionRecord

    record type: EL
    '''
    def _get_struct_type(self):
        return super(VersionRecord, self)._get_struct_type() + 'LHhL32s32sLLhh'
    def __str__(self):
        return str(self._data)
    @property
    def previous(self):
        return self._data[3]
    @property
    def action(self):
        return self._data[4]
    @property
    def datetime(self):
        return self._data[6]

class VersionFile(File):

    HEADER_SIZE = 52

    def __init__(self, filename):
        super(VersionFile, self).__init__(filename)
        self._read()
        self._versions = []

    def info(self):
        if not hasattr(self, '_info'):
            self._info = ItemRecord(self._data, self.HEADER_SIZE)
        return self._info

    def last_label(self):
        if self.info().isfile:
            return None
        def f(entry):
            return entry.action == ACTION_LABELED
        return self.history_last(f)

    def history_until(self, w=lambda x: True, f=None):
        v = []
        offset = self.info().last_version
        for entry in self._versions:
            if not w(entry):
                return v
            if not f or f(entry):
                v.append(entry)
            offset = entry.previous
        while offset > 0:
            entry = VersionRecord(self._data, offset)
            self._versions.append(entry)
            if not w(entry):
                return v
            if not f or f(entry):
                v.append(entry)
            offset = entry.previous
        return v

    def history_last(self, f=lambda x: True):
        offset = self.info().last_version
        for entry in self._versions:
            if f(entry):
                return entry
            offset = entry.previous
        while offset > 0:
            entry = VersionRecord(self._data, offset)
            self._versions.append(entry)
            if f(entry):
                return entry
            offset = entry.previous
        return None

    def __str__(self):
        return super(VersionFile, self).__str__()
